package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.FundAccountFlowTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.OtherExpenseSheetTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.domain.entity.FundAccountFlowEntity;
import com.xbongbong.saas.domain.entity.OtherExpenseEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.OtherExpenseEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.workflow.PayAndPaymentSheetHelp;
import com.xbongbong.saas.model.FundAccountFlowModel;
import com.xbongbong.saas.model.OtherExpenseModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 其他支出单
 * @author 魏荣杰
 *
 */
@Service
public class WorkflowOtherExpenseStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {

    private static Logger log = LoggerFactory.getLogger(WorkflowOtherExpenseStrategy.class);


    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private OtherExpenseModel otherExpenseModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private PayAndPaymentSheetHelp payAndPaymentSheetHelp;
    @Resource
    private FundAccountFlowModel fundAccountFlowModel;

    @Override
    public List<Integer> type() {
        return Collections.singletonList(XbbRefTypeEnum.OTHER_EXPENSE.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject dataList = pojoData.getData();
        Long dataId = pojoData.getId();
        String corpid = workflowTransferPOJO.getCorpid();
        Long formId = pojoData.getFormId();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        OtherExpenseEntity otherExpenseEntity = otherExpenseModel.getByKey(dataId, corpid);
        Double sheetAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(dataList, OtherExpenseEnum.AMOUNT.getAttr(), 0D);
        Long accountId = FastJsonHelper.getLongOrDefaultFromFormData(dataList, OtherExpenseEnum.FUND_ACCOUNT.getAttr(), 0L);
        Long sheetTime = fundHelp.getSheetTime4FundFlow(dataList, OtherExpenseEnum.EXPENSE_TIME.getAttr(), explainMap, otherExpenseEntity.getAddTime());
        String type = FastJsonHelper.getStringFromFormData(dataList, OtherExpenseEnum.SHEET_TYPE_OTHER.getAttr());
        if (Objects.equals(type, OtherExpenseSheetTypeEnum.OTHER_EXPENSE.getCode())) {
            sheetAmount = - sheetAmount;
        }
        payAndPaymentSheetHelp.saveByPaymentSheetOrPaySheet(accountId, sheetAmount, corpid);
        //流水表日志记录
        FundAccountFlowEntity fundAccountFlowEntity = new FundAccountFlowEntity(corpid, otherExpenseEntity.getAddTime(), otherExpenseEntity.getCreatorId(), FundAccountFlowTypeEnum.OTHER_EXPENSE.getCode(), dataId, accountId, sheetTime, sheetAmount);
        fundAccountFlowModel.insert(fundAccountFlowEntity);
        // api
        apiHook(workflowTransferPOJO);
        addLinkDataDynamic(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        //这边工作流编辑进审批不需要走主表的save操作
        //save(workflowTransferPOJO, saasNeedRedundantAttrPojo);
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);
        // api
        apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Long backupDataId = workflowTransferPOJO.getBackupDataId();
            Long dataId = workflowTransferPOJO.getData().getId();
            WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
            if (Objects.nonNull(workflowBackupDataEntity)) {
                JSONObject data = workflowBackupDataEntity.getData();

                replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

                OtherExpenseEntity otherExpenseEntity = new OtherExpenseEntity();
                otherExpenseEntity.setId(dataId);
                otherExpenseEntity.setCorpid(corpid);
                otherExpenseEntity.setData(data);
                otherExpenseEntity.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
                otherExpenseEntity.setOwnerId(getOwnerId(data));
                otherExpenseEntity.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));
                FormDataUtil.removeSystemData(data);
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                    otherExpenseEntity.setFlowStatus(FlowStatusEnum.PASS.getType());
                }
                otherExpenseModel.update(otherExpenseEntity);

                // 回退被删掉的子表单
                updateBackSubForm(otherExpenseEntity, corpid, IndexTypeEnum.IDX_SAAS_OTHER_EXPENSE_SUB);
                //回退被删掉的富文本
                updateBackRichText(taskId, workflowTransferPOJO);
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowOtherExpenseStrategy.updateBack error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            OtherExpenseEntity otherExpenseEntity = new OtherExpenseEntity();
            otherExpenseEntity.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                otherExpenseEntity.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                otherExpenseEntity.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            otherExpenseEntity.setCorpid(corpid);
            otherExpenseEntity.setUpdateTime(DateTimeUtil.getInt());
            otherExpenseModel.update(otherExpenseEntity);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;

            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_OTHER_EXPENSE_SUB, del);
            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);

        }catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowOtherExpenseStrategy.approvalFailed error ", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
